<?php

namespace app\modules\backend\controllers;

use app\models\tableModel\BlockModel;
use app\models\tableModel\NewsCategoryModel;
use app\service\tool\RequestService;
use app\service\tool\UtilsService;
use \yii\console\Exception as consoleException;
use yii\filters\AccessControl;
use yii\filters\VerbFilter;

/**
 * 碎片管理
 * User: Administrator
 * Date: 2021/12/31
 * Time: 14:24:53
 */
class BlockController extends BaseController
{

    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'verbs'  => [ // 请求方式
                'class'   => VerbFilter::className(),
                'actions' => [
                    ### 页面
                    'index-page' => ['GET'],
                    'render-page' => ['GET'],
                    ### 接口
                    'setting' => ['GET'],
                    'detail' => ['GET'],
                    'create' => ['POST'],
                    'update' => ['POST'],
                ],
            ]
        ];
    }


    /**
     * 列表页面
     * @return mixed
     */
    public function actionIndexPage()
    {

        return $this->render('index', []);
    }

    /**
     * 页面渲染
     */
    public function actionRenderPage()
    {

        // 参数编号
        $id = $this->get('id');
        if (!$id) return $this->showError('分类未找到', 404, [
            'reasons'      => ['分类编号未传输，请检查参数'],
            'redirectList' => false
        ]);

        // 设备
        $device = $this->get('device');
        if ($device == 'mobile') {

            // 模拟手机端UA
            $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1';
        }

        // 分类详情
        $category = NewsCategoryModel::loadModel();
        // 子集列表
        $childItem = [];
        switch ($id) {
            case -1: // 渲染首页
                // 无需操作 渲染指定 url
                break;
            default:
                // 分类详情
                $category = NewsCategoryModel::findOne($id);
                // 分类未找到
                if (!$category) return $this->showError('分类不存在', 404, [
                    'reasons'      => ['分类不合法，请检查参数'],
                    'redirectList' => false
                ]);
                // 站外链接
                if ($category->getAttribute('url_type') == $category::getUrlTypeOutside()
                    && !RequestService::isUrl($category->getAttribute('url'))
                ) {
                    return $this->showError('分类连接 ' .
                        $category->getAttribute('url') . ' 无法渲染', 400,
                        [
                            'reasons'      => ['分类连接为非正常连接', '其他未知错误'],
                            'redirectList' => false
                        ]
                    );
                }
                // 子集列表
                $childItem = NewsCategoryModel::findOne([
                    'parent_id' => $id
                ]);
                break;
        }

        // 渲染详情页面 参数
        $renderDetail = $this->get('render_detail', false, 'bool');
        // 渲染具体连接 参数
        $renderUrl = $this->get('render_url', false, 'string');

        // 碎片编辑中状态赋值
        BlockModel::blockIsEditing();

        ### 渲染的模板
        $template = '';

        // 渲染详情参数 - 直接渲染详情
        if ($renderDetail) {
            $template = $category->getAttribute('detail_template');
        } // 渲染具体连接
        else if ($renderUrl) {
            $rules = \Yii::$app->getUrlManager()->rules;
            $rules = json_decode(json_encode($rules, JSON_UNESCAPED_UNICODE), true);
            $rules = array_column($rules, null, 'name');

            // 模板未找到
            if (empty($rules[$renderUrl])) return $this->showError(
                '连接未找到，请检查url配置', 404
            );

            try {
                return \Yii::$app->runAction($rules[$renderUrl]['route']);
            } catch (\Exception $error) {
                return $this->showError(
                    '连接无法渲染，请查看错误日志', 500
                );
            }
        } // 没有子集 && 渲染详情参数否 - 渲染列表页面
        else if (!$childItem) {
            $template = $category->getAttribute('list_template');
        } // 渲染详情
        else {
            $template = $category->getAttribute('cate_template');
        }

        try {
            $controller = \Yii::$app->createController('frontHtml/base');
            $controller = current($controller);
            $this->layout = $controller->layout;
        } catch (\Exception $error) {
            return $this->showError('连接无法渲染，请查看错误日志', 500, [
                'reasons' => [$error->getMessage()]
            ]);
        }

        return @$this->render('@template' . $template);
    }


    /**
     * 获取设置
     *  ` PS: 获取某些设置(如：状态列表等)以供前端使用
     * @return mixed
     */
    public function actionSetting()
    {

        // 左侧定界符
        $lefDeli = empty(
        \Yii::$app->components['view']['renderers']['tpl']['options']['left_delimiter']
        ) ? null : \Yii::$app->components['view']['renderers']['tpl']['options']['left_delimiter'];
        // 右侧定界符
        $rightDeli = empty(
        \Yii::$app->components['view']['renderers']['tpl']['options']['right_delimiter']
        ) ? null : \Yii::$app->components['view']['renderers']['tpl']['options']['right_delimiter'];

        // 类型 - 一般为首页[index]、表单[form]
        $type = $this->get('type');
        // 模型
        $model = BlockModel::loadModel();
        return $this->jsonSuccess('成功', [
            'default_status'      => !empty($type) && $type == 'index' ?
                '' : $model::getStatusOpen(), // 默认选中状态
            'default_type'        => !empty($type) && $type == 'index' ?
                $model::getTypeHtml() : $model::getTypeHtml(), // 默认选中状态
            'default_limit'       => 10, // 默认条目数
            'type_list'           => $model::getTypeList(), // 类型列表值
            'data_type_list'      => $model::getDataTypeList(), // 数据字段类型 列表值
            'status_list'         => $model::getStatusList(), // 状态列表值
            'min_limit'           => $model::getMinLimit(), // 最小条目数
            'max_limit'           => $model::getMaxLimit(), // 最大条目数
            'left_delimiter'      => $lefDeli,
            'right_delimiter'     => $rightDeli
        ]);
    }

    /**
     * 详情
     * @param string $id 编号
     * @return mixed
     */
    public function actionDetail()
    {

        // 获取全部POST数据
        $id = $this->get('id');

        // 验证 规格编号
        if (empty($id)) {

            return $this->jsonFail('数据不存在', 404, [
                'error_hint' => '请传输编号',
                'error_code' => 400
            ]);
        }

        $model = BlockModel::loadModel($id);

        if ($model == null) {

            return $this->jsonFail('数据不存在', 404, [
                'error_hint' => '数据不存在，请核对',
                'error_code' => 404
            ]);
        }

        // 仅仅返回指定 字段
        $detail = $model->getAttributes([
            'id',
            'name',
            'pos',
            'type',
            'limit',
            'template',
            'data',
            'data_column',
            'status',
            'add_time',
            'update_time',
        ]);
        $detail = BlockModel::formatData($detail);

        return $this->jsonSuccess('成功', $detail);
    }

    /**
     * 创建
     * @return mixed
     */
    public function actionCreate()
    {

        // 赋值所需数据
        $data = [
            'name'        => $this->post('name'),
            'pos'         => $this->post('pos'),
            'type'        => $this->post('type'),
            'limit'       => $this->post('limit', 0),
            'data'        => $this->post('data', []),
            'data_column' => $this->post('data_column'),
            'template'    => $this->post('template'),
            'status'      => BlockModel::getStatusOpen(),
        ];

        $tran = \Yii::$app->db->beginTransaction();
        try {


            ### 保存碎片信息
            // 实例化类
            $model = BlockModel::loadModel();
            // 加载类数据
            $model->load($data, '');

            // 数据保存失败并返回错误信息
            if (!$model->save()) {

                $tran->rollBack();
                $error = $model->getFirstErrors();
                return $this->jsonFail('添加失败, 请确认各项数据是否合法', 400, [
                    'columnError' => UtilsService::getChineseErr($error)
                ]);
            }

            $tran->commit();
            // 成功返回
            return $this->jsonSuccess('成功', [
                'id' => $model->getAttribute('id')
            ]);
        } catch (\Exception $error) {

            // 记录下错误日志
            \Yii::error([

                "`````````````````````````````````````````````````````````",
                "``                      添加碎片错误                      ``",
                "`` 错误详情: [碎片]添加失败                                 ``",
                "``         {$error->getMessage()}                       ``",
                "`` 错误信息和参数详情:                                     ``",
                "`````````````````````````````````````````````````````````",
                $error->getTraceAsString()
            ], 'error');

            $tran->rollBack();
            return $this->jsonFail('修改失败', 500, [
                'errorHint' => $error->getMessage()
            ]);
        }
    }

    /**
     * 更新
     * @return mixed
     */
    public function actionUpdate()
    {

        // 编号
        $id = $this->post('id');

        // 实例化类 - 并根据编号查询
        $model = BlockModel::loadModel($id);
        // 编号非法返回
        if (empty($model)) {

            return $this->jsonFail('数据不存在', 400, [
                'error_hint' => '请传输编号',
                'error_code' => 400
            ]);
        }

        // 赋值所需数据
        $data = [
            'id'          => $this->post('id'),
            'name'        => $this->post('name'),
            'pos'         => $this->post('pos'),
            'type'        => $this->post('type'),
            'limit'       => $this->post('limit', 0),
            'data'        => $this->post('data', []),
            'data_column' => $this->post('data_column'),
            'template'    => $this->post('template'),
            'status'      => $this->post('status'),
            'add_time'    => $this->post('add_time'),
            'update_time' => $this->post('update_time'),
        ];


        $tran = \Yii::$app->db->beginTransaction();
        try {

            ### 保存碎片信息
            // 加载类数据
            $model->load($data, '');
            if (!$model->save()) {

                $tran->rollBack();
                $error = UtilsService::getModelError($model->getErrors());
                return $this->jsonFail('修改失败, 请确认各项数据是否合法', 400, [
                    'columnError' => $error['msg']
                ]);
            }

            ### 将使用的图片改为已使用
            // 取出已使用图片列表
            $newImgList = [];
            // 确保字段不为空
            $data['data_column'] = empty($data['data_column']) ? [] : $data['data_column'];
            foreach ($data['data_column'] as $k => $v) {
                // 非图片类型字段舍弃
                if ($v['type'] != BlockModel::getDataTypeImage()) continue;
                // 图片添加进去
                $newImgList = array_merge($newImgList,
                    array_column($data['data'], $v['name']));
            }


            $tran->commit();
            // 成功返回
            return $this->jsonSuccess('成功');
        } catch (\Exception $error) {

            // 记录下错误日志
            \Yii::error([

                "`````````````````````````````````````````````````````````",
                "``                      更新碎片错误                      ``",
                "`` 错误详情: [碎片]更新失败                                 ``",
                "``         {$error->getMessage()}                       ``",
                "`` 错误信息和参数详情:                                     ``",
                "`````````````````````````````````````````````````````````",
                $error->getTraceAsString()
            ], 'error');

            $tran->rollBack();
            return $this->jsonFail('修改失败', 500, [
                'errorHint' => $error->getMessage()
            ]);
        }
    }
}
